package middleware

import (
	"bytes"
	"crypto/aes"
	"crypto/cipher"
	"encoding/base64"
	"errors"
	"io"
	"net/http"

	"github.com/gin-gonic/gin"
)

// AESKey，生产环境建议从配置文件读取
var AESKey = []byte("1234567890123456") // 16 字节

// AESDecryptMiddleware 全局请求解密中间件
func AESDecryptMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		// 仅对 POST/PUT 请求解密
		if c.Request.Method != http.MethodPost && c.Request.Method != http.MethodPut {
			c.Next()
			return
		}

		var req struct {
			Data string `json:"data"`
		}
		if err := c.ShouldBindJSON(&req); err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"error": "请求体解析失败"})
			c.Abort()
			return
		}

		// AES 解密
		plain, err := decryptAESGCM(req.Data)
		if err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"error": "解密失败"})
			c.Abort()
			return
		}

		// 将解密后的 JSON 放到 Context，供后续 handler 使用
		c.Set("DECRYPTED_BODY", plain)

		// 重置请求体，方便 handler 再次读取
		c.Request.Body = io.NopCloser(bytes.NewBufferString(plain))

		c.Next()
	}
}

// AES 解密函数（CFB 模式）
func decryptAESGCM(cipherTextBase64 string) (string, error) {
	cipherText, err := base64.StdEncoding.DecodeString(cipherTextBase64)
	if err != nil {
		return "", err
	}

	if len(cipherText) < 12 {
		return "", errors.New("密文太短")
	}

	block, err := aes.NewCipher(AESKey)
	if err != nil {
		return "", err
	}

	gcm, err := cipher.NewGCM(block)
	if err != nil {
		return "", err
	}

	nonce := cipherText[:gcm.NonceSize()]
	cipherTextData := cipherText[gcm.NonceSize():]

	plain, err := gcm.Open(nil, nonce, cipherTextData, nil)
	if err != nil {
		return "", err
	}

	return string(plain), nil
}
